const { pollRegisters } = require('./modbusCommunication');
const { modbusStatusHandle, photoHandle, finishToWcsHandle } = require('./modbusBuness');

// 引入需要的常量
const flagList = [32, 33];
const writeModBusList = [
  Array.from({ length: 25 }, (_, i) => i * 2 + 1),
  Array.from({ length: 25 }, (_, i) => i * 2 + 51),
  Array.from({ length: 25 }, (_, i) => i * 2 + 101),
  Array.from({ length: 25 }, (_, i) => i * 2 + 151),
];

// 全局状态变量
let isPolling = true; // 是否处于轮询模式
let isProcessingQueue = false; // 是否正在处理队列
let pendingWriteRequests = []; // 等待处理的写入请求队列
let pollingTimer = null; // 轮询定时器
let processingTimer = null; // 处理定时器

// 从modbusBuness导入需要的变量
let writingConfig;
let aryModbusStatusList;

// 初始化函数
function initHybridMode(modbusStatusList, writeConfig) {
  aryModbusStatusList = modbusStatusList;
  writingConfig = writeConfig;
}

// 开始轮询模式
function startPollingMode(client, socket) {
  if (isPolling) return; // 已经在轮询模式中
  
  isPolling = true;
  console.log('切换到轮询模式');
  
  // 启动轮询定时器
  pollingTimer = setInterval(async () => {
    try {
      // 使用 setImmediate 确保轮询操作不会阻塞事件循环
      await new Promise(resolve => setImmediate(resolve));
      
      // 读取机器人状态
      await readRobotStatus(client, socket);
      
      // 更新前端显示
      if (socket && socket.connected) {
        const fullData = aryModbusStatusList.flat();
        socket.emit("modBusStatus", {
          message: "modBus协议，机器人状态",
          inputData: fullData,
        });
      }
    } catch (error) {
      console.error('轮询过程中出错:', error.message);
    }
  }, 500); // 500ms轮询间隔
}

// 停止轮询模式
function stopPollingMode() {
  if (!isPolling) return; // 已经停止轮询
  
  isPolling = false;
  if (pollingTimer) {
    clearInterval(pollingTimer);
    pollingTimer = null;
  }
  console.log('轮询模式已停止');
}

// 读取机器人状态（异步非阻塞）
async function readRobotStatus(client, socket) {
  console.log('开始异步读取机器人状态');
  try {
    // 异步读取标志位
    let flagValue = await client.safeReadInputRegisters(flagList[0], flagList.length);
    
    if (flagValue && flagValue[0] === 1) {
      // 异步读取全部200个寄存器
      let statusList = await client.safeReadInputRegisters(0, 200);

      if (statusList) {
        // 清空数组并更新数据
        aryModbusStatusList.length = 0;

        // 使用 Promise.all 来并行处理数据分组（如果需要更高性能）
        const groupedData = [];
        for (let j = 0; j < statusList.length; j += 25) {
          groupedData.push(statusList.slice(j, j + 25));
        }

        // 更新全局状态列表
        aryModbusStatusList.push(...groupedData);
      }
    }
  } catch (error) {
    console.error("异步读取机器人状态失败:", error.message);
    // 可选：上报错误给前端
    if (socket?.connected) {
      socket.emit("error", { message: "读取机器人状态失败", error: error.message });
    }
  } finally {
    console.log('完成异步读取机器人状态');
  }
}

// 添加写入请求到队列
function enqueueWriteRequest(writeData) {
  pendingWriteRequests.push(writeData);
  console.log(`写入请求已添加到队列，当前队列长度: ${pendingWriteRequests.length}`);
  
  // 如果有队列任务且不在处理中，则启动处理
  if (!isProcessingQueue && pendingWriteRequests.length > 0) {
    isProcessingQueue = true;
    stopPollingMode(); // 停止轮询模式
    console.log('切换到事件驱动模式');
  }
}

// 处理队列中的写入请求
async function processWriteQueue(client, socket) {
  if (processingTimer) return; // 已经在处理中
  
  processingTimer = setInterval(async () => {
    if (pendingWriteRequests.length === 0) {
      // 队列为空，停止处理并恢复轮询
      isProcessingQueue = false;
      clearInterval(processingTimer);
      processingTimer = null;
      startPollingMode(client, socket); // 恢复轮询模式
      console.log('队列处理完成，切换回轮询模式');
      return;
    }
    
    // 处理队列中的下一个请求
    const writeRequest = pendingWriteRequests[0];
    try {
      await processWriteRequest(client, socket, writeRequest);
      // 处理成功后从队列中移除
      pendingWriteRequests.shift();
    } catch (error) {
      console.error('处理写入请求时出错:', error.message);
      // 出错也移除请求，避免阻塞队列
      pendingWriteRequests.shift();
    }
  }, 100); // 100ms检查间隔
}

// 处理单个写入请求
async function processWriteRequest(client, socket, writeRequest) {
  const { proData, cameraClient, req } = writeRequest;
  const index = (proData.beUsed || 1) - 1;
  
  // 检查机器人状态是否为运行中(状态为1)
  const { robotStatus, robotPosition } = modbusStatusHandle(index);
  
  if (robotStatus != 1) {
    console.log(`机器人${index + 1}未运行，当前状态: ${robotStatus}`);
    return;
  }
  
  // 读取32,33地址的数据是否为1
  let flagValue = await client.safeReadInputRegisters(flagList[0], flagList.length);
  if (!flagValue || flagValue[0] != 1) {
    console.log(`机器人${index + 1}标志位不为1，当前值: ${flagValue ? flagValue[0] : 'null'}`);
    return;
  }
  
  // 构造写入数据
  let lineNum = 0;
  if (proData.lineName == "A") {
    lineNum = 1;
  } else if (proData.lineName == "B") {
    lineNum = 2;
  }
  
  const data = [
    proData.id || 0, // id
    proData.long || 0, // 默认长
    proData.wide || 0, // 默认宽
    proData.height || 0, // 默认高
    proData.palletizingNum || 0, // 码垛层数
    proData.layerNum || 0, // 每件个数
    0, // 中心点x
    0, // 中心点y
    0, // 中心点z
    0, // 实际长
    0, // 实际宽
    0, // 实际高
    1, // 托盘到位状态
    0, // 拍照完成
    proData.grippingDirection || 0, // 抓取方向
    proData.presetsNum || 0, // 当前产品码垛数量
    lineNum, // 码垛位置
    1, // 数据发送
    0, // 中心点RZ
    0, // 托盘到B位
    0, // 是否启用 1为启用 2为停用
    0, // 备用
    0, // 备用
    0, // 备用
    0, // 备用
  ];
  
  // 更新writingConfig
  writingConfig[index] = [...data];
  
  // 写入数据到PLC
  const targetAddresses = writeModBusList[index];
  const valuesToWrite = writingConfig[index];
  
  // 准备批量写入请求
  const writeRequests = [];
  for (let j = 0; j < targetAddresses.length && j < valuesToWrite.length; j++) {
    const registerAddress = targetAddresses[j] - 1; // 地址从0开始
    const value = valuesToWrite[j];
    // 使用modbusClient内部的_floatToRegisters方法
    const registers = client._floatToRegisters(value);
    
    writeRequests.push({
      address: registerAddress,
      values: registers,
    });
  }
  
  // 执行批量写入
  await client.safeWriteMultipleRegisterArrays(writeRequests);
  console.log(`机器人${index + 1}数据写入完成`);
  
  // 再次检查32,33地址的数据是否为1
  flagValue = await client.safeReadInputRegisters(flagList[0], flagList.length);
  if (!flagValue || flagValue[0] != 1) {
    console.log(`写入后检查标志位，机器人${index + 1}标志位不为1`);
    return;
  }
  
  // 再次获取机器人状态，检查是否可以拍照
  await handlePhotoProcess(client, socket, index, proData);
}

// 处理拍照流程
async function handlePhotoProcess(client, socket, index, proData) {
  // 检查是否可以拍照
  const { robotStatus, robotPosition, robotPhotoStatus, robotOneFinished } = modbusStatusHandle(index);
  
  // 检查是否满足拍照条件
  if (robotStatus == 1 && robotPosition == 2 && robotPhotoStatus == 1 && robotOneFinished != 1) {
    console.log(`机器人${index + 1}满足拍照条件，开始拍照处理`);
    
    // 调用拍照处理函数
    await photoHandle(index, socket);
    
    // 拍照完成后再次检查状态
    await handleFinishProcess(client, socket, index, proData);
  } else {
    console.log(`机器人${index + 1}不满足拍照条件: 
      robotStatus=${robotStatus}, 
      robotPosition=${robotPosition}, 
      robotPhotoStatus=${robotPhotoStatus}, 
      robotOneFinished=${robotOneFinished}`);
  }
}

// 处理完成流程
async function handleFinishProcess(client, socket, index, proData) {
  // 检查码垛是否完成
  const { robotStatus, robotPosition, robotAllFinished, robotOneFinished } = modbusStatusHandle(index);
  
  // 检查是否满足完成条件
  if (robotStatus == 1 && robotPosition == 0 && robotOneFinished == 1) {
    console.log(`机器人${index + 1}码垛完成，发送完成信号`);
    
    // 发送码垛完成信号
    await finishToWcsHandle(index, socket);
    
    console.log(`机器人${index + 1}任务完成，清理标志位`);
    // 清理标志位等后续处理可以在这里添加
  } else {
    console.log(`机器人${index + 1}未完成码垛: 
      robotStatus=${robotStatus}, 
      robotPosition=${robotPosition}, 
      robotAllFinished=${robotAllFinished}, 
      robotOneFinished=${robotOneFinished}`);
  }
}

// 获取当前模式状态
function getModeStatus() {
  return {
    isPolling,
    isProcessingQueue,
    queueLength: pendingWriteRequests.length
  };
}

module.exports = {
  initHybridMode,
  startPollingMode,
  stopPollingMode,
  enqueueWriteRequest,
  processWriteQueue,
  getModeStatus
};